package com.lsh.ofc.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lsh.base.common.exception.BusinessException;
import com.lsh.ofc.core.constant.Constants;
import com.lsh.ofc.core.entity.*;
import com.lsh.ofc.core.enums.*;
import com.lsh.ofc.core.exception.EC;
import com.lsh.ofc.core.service.*;
import com.lsh.ofc.core.util.IdGenerator;
import com.lsh.ofc.proxy.context.WumartBasicContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Project Name: Order4PCServiceImpl
 * 北京链商电子商务有限公司
 * Auth: wangliutao
 * Date: 18/8/8
 * Package Name: com.lsh.ofc.core.service.impl
 * Description:
 */
@Service
public class Order4PCServiceImpl implements Order4PCService {
    private static final Logger logger = LoggerFactory.getLogger(Order4PCServiceImpl.class);

    @Autowired
    private OfcStoCreateService ofcStoCreateService;

    @Autowired
    private OfcCustomerService ofcCustomerService;

    @Autowired
    private OfcSoService ofcSoService;

    @Override
    public void createOrder(String content) throws BusinessException {
        JSONObject json = JSON.parseObject(content);
        Long orderCode = json.getLong("orderCode");
        Integer regionCode = json.getInteger("regionCode");

        if (orderCode == null || orderCode.longValue() == 0L) {
            throw EC.ERROR_PARAMS.exception("orderCode is null");
        }
        if (regionCode == null || regionCode.intValue() == 0) {
            throw EC.ERROR_PARAMS.exception("regionCode is null");
        }

        OfcSoHead filter = new OfcSoHead();
        filter.setOrderCode(orderCode);
        List<OfcSoHead> list = this.ofcSoService.findList(filter, false);
        if (!CollectionUtils.isEmpty(list)) {
            logger.info("orderCode already exists！！ orderCode is {}", orderCode);
            return;
        }

        List<JSONObject> items = JSON.parseArray(json.getString("items"), JSONObject.class);

        OfcOrderHead ofcOrderHead = this.buildOfcOrderHead(orderCode, regionCode, items);
        OfcSoHead ofcSoHead = this.buildSoHead(ofcOrderHead);

        // 创建OfcOrderHead、OfcSoHead
        ofcStoCreateService.create(ofcOrderHead, Collections.singletonList(ofcSoHead));
    }

    private OfcOrderHead buildOfcOrderHead(Long orderCode, Integer regionCode, List<JSONObject> items) throws BusinessException {
        OfcOrderHead orderHead = new OfcOrderHead();
        orderHead.setOrderCode(orderCode);
        orderHead.setRegionCode(regionCode);

        BigDecimal totalQty = BigDecimal.ZERO;
        ArrayList<OfcOrderDetail> details = new ArrayList<>();
        HashSet<Integer> itemNos = new HashSet<>(items.size());
        for (JSONObject item : items) {
            Integer itemNo = item.getInteger("itemNo");
            String goodsName = item.getString("goodsName");
            BigDecimal goodsQty = item.getBigDecimal("goodsQty");
            //物美码
            Long supplyCode = item.getLong("goodsCode");

            if (goodsQty == null || goodsQty.equals(BigDecimal.ZERO)
                    || supplyCode == null || supplyCode.longValue() == 0L) {
                throw EC.ERROR_PARAMS.exception("item param is wrong");
            }

            OfcOrderDetail detail = this.buildOfcOrderDetail(orderCode, supplyCode, goodsName, goodsQty);
            totalQty = totalQty.add(goodsQty);
            details.add(detail);
            itemNos.add(itemNo);
        }

        if (itemNos.size() != items.size()) {
            throw EC.ERROR_PARAMS.exception("itemNo is wrong");
        }

        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        orderHead.setAddressCode(10000000001L);
        orderHead.setAddressInfo(this.initAdressInfo().toJSONString());
        // 调拨单默认金额为0
        orderHead.setOrderAmount(BigDecimal.ZERO);
        orderHead.setOrderTime(time);
        orderHead.setWarehouseCode("DC30");
        orderHead.setWarehouseName("昌平猪肉常温库");
        orderHead.setTotalSkuSupplyQty(BigDecimal.ZERO);
        orderHead.setTotalSkuDeliverQty(BigDecimal.ZERO);
        orderHead.setTotalSkuReturnQty(BigDecimal.ZERO);
        orderHead.setFulfillStatus(FulfillStatus.NEW.getValue());

        // 来自customer
        OfcCustomer customer = this.getCustomer(orderHead);
        Map<String, String> ext = new HashMap<>();
        ext.put(Constants.ORDER_H_MP_CUST_CODE, customer.getMpCustCode());
        ext.put(Constants.ORDER_H_TRANS_TIME, String.valueOf(time));
        ext.put(Constants.OFC_ORDER_LOGISTICS_MODE, LogisticsTypeEnum.WUMART_PC.getType().toString());
        orderHead.setExt(JSON.toJSONString(ext));
        orderHead.setUpdateTime(time);
        orderHead.setCreateTime(time);
        // 是否二次配送 0否 1是
        orderHead.setSecondDistributionFlag(0);
        // 配送模式 给大值
        orderHead.setDistributionWay(90);
        orderHead.setPreWarehouseCode("0");
        orderHead.setOrderDistributionType(DistributionType.ORDER_SO.getCode());
        orderHead.setTotalSkuOrderQty(totalQty);
        orderHead.setDetails(details);

        return orderHead;
    }

    private OfcOrderDetail buildOfcOrderDetail(Long orderCode, Long supplyCode, String goodsName, BigDecimal goodsQty) {
        OfcOrderDetail detail = new OfcOrderDetail();

        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        detail.setOrderCode(orderCode);
        // skuCode、goodsCode、skuSupplyCode都是supplyCode
        detail.setGoodsCode(supplyCode);
        detail.setGoodsName(goodsName);
        detail.setGoodsSaleUnit(BigDecimal.ONE);
        detail.setGoodsPrice(BigDecimal.ZERO);
        detail.setGoodsQty(goodsQty);
        detail.setGoodsAmount(BigDecimal.ZERO);
        // 填充goodsCode对应的skuCode
        detail.setSkuCode(supplyCode);
        // skuQty = goodsQty * goodSaleUnit; 此处goodSaleUnit = 1
        detail.setSkuQty(goodsQty);
        // todo
        detail.setExt(null);
        detail.setCreateTime(time);
        detail.setUpdateTime(time);

        return detail;
    }

    private OfcSoHead buildSoHead(OfcOrderHead ofcOrderHead) {
        OfcSoHead ofcSoHead = new OfcSoHead();
        ofcSoHead.setSoBillCode(IdGenerator.getId());
        // 来自汇总so信息
        ofcSoHead.setOrderCode(ofcOrderHead.getOrderCode());
        ofcSoHead.setOrderTime(ofcOrderHead.getOrderTime());
        ofcSoHead.setRegionCode(ofcOrderHead.getRegionCode());
        ofcSoHead.setAddressCode(ofcOrderHead.getAddressCode());
        ofcSoHead.setWarehouseCode(ofcOrderHead.getWarehouseCode());
        ofcSoHead.setWarehouseName(ofcOrderHead.getWarehouseName());
        ofcSoHead.setSupplierId(0);
        ofcSoHead.setSupplierDc("DC30");
        ofcSoHead.setSupplierOrg(1);
        ofcSoHead.setFulfillWms(1);
        ofcSoHead.setFulfillChannel(2);
        ofcSoHead.setSoStatus(SoStatus.UNCREATED.getValue());
        ofcSoHead.setTotalSkuOrderQty(ofcOrderHead.getTotalSkuOrderQty());
        ofcSoHead.setTotalSkuSupplyQty(ofcOrderHead.getTotalSkuSupplyQty());
        ofcSoHead.setTotalSkuDeliverQty(ofcOrderHead.getTotalSkuDeliverQty());
        ofcSoHead.setTotalSkuReturnQty(ofcOrderHead.getTotalSkuReturnQty());

        // 组织ext 信息
        JSONObject ext_so = JSON.parseObject(ofcOrderHead.getExt());
        ext_so.put(Constants.SO_H_SUPPLIER_CODE, ofcOrderHead.getPreWarehouseCode());
        Integer transTime = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        ext_so.put(Constants.SO_H_TRANS_TIME, transTime.toString());
        ext_so.put(WumartBasicContext.CUSTYPE, CusType.WG_WM.getValue());
        // TODO 2019-04-09 兼容提交物美ofc逻辑
        ext_so.put(Constants.SO_H_LGORT_TYPE, LgortType.WUMART_DC.getCode());

        ofcSoHead.setExt(JSON.toJSONString(ext_so));
        ofcSoHead.setSecondDistributionFlag(ofcOrderHead.getSecondDistributionFlag());
        ofcSoHead.setDistributionWay(ofcOrderHead.getDistributionWay());
        ofcSoHead.setOrderDistributionType(ofcOrderHead.getOrderDistributionType());
        ofcSoHead.setPreWarehouseCode(ofcOrderHead.getPreWarehouseCode());

        ofcSoHead.setDetails(this.buildSoDetail(ofcSoHead, ofcOrderHead));
        return ofcSoHead;
    }

    private List<OfcSoDetail> buildSoDetail(OfcSoHead soHead, OfcOrderHead ofcOrderHead) {
        ArrayList<OfcSoDetail> details = new ArrayList<>();

        int no = 1;
        int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        for (OfcOrderDetail ofcOrderDetail : ofcOrderHead.getDetails()) {
            OfcSoDetail detail = new OfcSoDetail();
            detail.setSoBillCode(soHead.getSoBillCode());
            detail.setItemNo(10 * no++);
            detail.setGoodsCode(ofcOrderDetail.getGoodsCode());
            detail.setGoodsName(ofcOrderDetail.getGoodsName());
            detail.setGoodsSaleUnit(ofcOrderDetail.getGoodsSaleUnit());
            detail.setGoodsPrice(ofcOrderDetail.getGoodsPrice());
            detail.setGoodsAmount(ofcOrderDetail.getGoodsAmount());
            detail.setSkuCode(ofcOrderDetail.getSkuCode());

            // todo
            detail.setSkuSupplyCode(String.format("%018d", ofcOrderDetail.getSkuCode()));
            detail.setSkuSupplyPrice(BigDecimal.ZERO);
            detail.setSkuOrderQty(ofcOrderDetail.getSkuQty());
            detail.setSkuSupplyQty(ofcOrderDetail.getSkuQty());
            detail.setSkuReturnQty(BigDecimal.ZERO);
            detail.setTaxRate(Constants.TAX_016);
            JSONObject ext = new JSONObject();
            ext.put("sku_define", SkuDefine.KG.getCode());
            // todo
            detail.setExt(ext.toJSONString());
            detail.setCreateTime(time);
            detail.setUpdateTime(time);

            details.add(detail);
        }
        return details;
    }

    private JSONObject initAdressInfo() {
        JSONObject addressInfo = new JSONObject();
        //超市名称
        addressInfo.put("market_name", "北京餐馆猪肉供给超市");
        addressInfo.put("province_name", "北京");
        addressInfo.put("city_name", "北京");
        addressInfo.put("county_name", "北京");
        addressInfo.put("address", "北京餐馆猪肉供给仓");
        addressInfo.put("contact_name", "北京餐馆猪肉供给仓");
        addressInfo.put("contact_phone", "00000000000");
        //坐标
        addressInfo.put("real_position", "0");
        //大车限行
        addressInfo.put("trans_limit", "0");
        // TODO
        addressInfo.put(Constants.ORDER_PRE_WAREHOUSE_CODE, "0");
        addressInfo.put(Constants.ORDER_PRE_WAREHOUSE_NAME, "");
        addressInfo.put(Constants.ORDER_DELIVERY_WAY, 90);
        addressInfo.put(Constants.ORDER_IS_IN_DMALL, 0);

        return addressInfo;
    }

    private OfcCustomer getCustomer(OfcOrderHead ofcOrderHead) throws BusinessException {
        //校验并更新用户信息
        OfcCustomer param = new OfcCustomer();
        JSONObject addressInfo = JSON.parseObject(ofcOrderHead.getAddressInfo());
        param.setRegionCode(ofcOrderHead.getRegionCode());
        param.setCustCode(ofcOrderHead.getAddressCode());
        param.setCustName(addressInfo.getString("market_name")); //超市名称
        param.setProvince(addressInfo.getString("province_name"));//省
        param.setCity(addressInfo.getString("city_name"));//市
        param.setDistrict(addressInfo.getString("county_name"));//区
        param.setAddress(addressInfo.getString("address")); //地址
        param.setContactName(addressInfo.getString("contact_name"));//联系人
        param.setContactPhone(addressInfo.getString("contact_phone")); //联系人电话
        param.setLocation(addressInfo.getString("real_position"));//坐标
        Integer transLimit = addressInfo.getInteger("trans_limit");//大车限行
        param.setExt(JSON.toJSONString(Collections.singletonMap(Constants.USER_ADDRESS_TRANS_LIMIT, transLimit)));
        param.setCusType(CusType.WG_WM.getValue()); // 猪肉采购客户号类型默认是4，文固采购。
        return this.ofcCustomerService.updateCustomer(param);
    }
}
